home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
SOUND
/
DSYMPLAY
/
DSymPlayer
/
DSym_Info
next >
Wrap
Text File
|
1996-10-23
|
57KB
|
1,277 lines
Digital Symphony revisions:
===========================
1) 12 Mar 1993 (DS 1.20, DSymPlay 1.01)
------------------------------------
Filetypes SySample and Symphony are now able to store 8-bit linear sample
data.
2) 30 Mar 1994 (DS 1.30, DSymPlay 1.30)
------------------------------------
Filetypes SySample and Symphony are now able to store 16-bit linear sample
data.
New compression scheme introduced.
We now play tunes at nearly exactly the speed an Am*ga does.
3) 01 Sep 1994 (DS 1.31, DSymPlay 1.30)
------------------------------------
4) 16 Jan 1995 (DS 1.31, DSymPlay 1.40)
------------------------------------
5) 23 Oct 1996 (DS 1.31, DSymPlay 1.41)
------------------------------------
Latest versions:
================
DSym_Play module: 1.41
Digital Symphony: 1.31
Symphony file: 1 (from DS 1.30 on)
SySample file: 1 (from DS 1.30 on)
Patterns file: 0
Major changes in DSymPlay from version 1.10 on:
===============================================
- Dynamic choice of the fastest routine given the processor (ARM 2 or >2).
- The load routine didn't release the unpacking buffer (32K) after
loading a packed song. Works now.
- Changed the specs of the CutNote SWI, sorry!
- StrongARM compatible
This file contains two main parts:
==================================
I. Effects commands and music files formats.
II. SWI's and commands of the Digital Symphony players.
======================================================================
PART I : Effect commands and music file formats of some music programs
======================================================================
1.1. Amiga ProTracker V1.1B Effect Commands
--------------------------------------
(x-y,z) indicates z is done if value not in the range x to y inclusive.
<command number in hex> <effect value in hex>
0 xy Normal play or Arpeggio.
x: first halfnote to add to pitch
y: second halftone to add to pitch
1 xx Slide Up.
xx: pitch increase step
2 xx Slide Down.
xx: pitch decrease step
3 xx Tone Portamento.
xx: pitch slide speed (0 for previous speed)
4 xy Vibrato.
x: pitch change speed (0 for previous speed)
y: pitch change depth (0 for previous depth)
5 xy Tone Portamento + Volume Slide.
x: volume increase step (priority)
y: volume decrease step
6 xy Vibrato + Volume Slide.
x: volume increase step (priority)
y: volume decrease step
7 xy Tremolo.
x: volume change speed (0 for previous speed)
y: volume change depth (0 for previous depth)
8 xx Not used.
9 xx Set Sample Offset.
xx: offset in sample DIV 256 (loop restarted if illegal)
0 for previous offset
A xy Volume Slide.
x: volume increase step (priority)
y: volume decrease step
B xx Position Jump.
xx: song position (0-127, masked, 0 if illegal)
C xx Set Volume.
xx: volume (0-64,rounded). Linear.
D xy Pattern Break.
10*x+y: position to jump to in next pattern (0-63, 0)
E 0x Set Filter.
x: filter on (0) or filter off (1) (or power LED on/off)
E 1x Fine Slide Up.
x: value to add to pitch
E 2x Fine Slide Down.
x: value to subtract from pitch
E 3x Glissando Control.
x: on (1) or off (0) (use with Tone Portamento)
When off, the slide is smooth else from halfnote to halfnote
E 4x Set Vibrato Waveform.
x: sine (0), ramp down (1), square (2)
bit 2 is off if wave form has to be restarted each note
E 5x Set Fine Tune.
x: new fine tune value
E 6x Jump to Loop.
x: jump to loop, play x times
if 0, the loop start is set to the current pattern position
E 7x Set Tremolo Waveform.
x: sine (0), ramp down (1), square (2)
bit 2 is off if wave form has to be restarted each note
E 8x Not used.
E 9x Retrig Note.
x: retrig note each (more or less) x vblanks
E Ax Fine Volume Slide Up.
x: value to add to volume
E Bx Fine Volume Slide Down.
x: value to subtract from volume
E Cx Note Cut.
x: cut note after x vblanks (volume is only set to 0)
E Dx Note Delay.
x: number of vblanks for note delay
E Ex Pattern Delay.
x: delay pattern x notes
E Fx Invert Loop.
x: speed
if 0, it's turned off
Care must be taken using it: it inverts the sign of sample data
inside sample loop, one byte each vblank
F xx Set Speed.
In CIA mode (recommended and most usual):
xx: speed (1-31,ignored) or tempo (32-255)
Tempo unit: 1/24th vblanks per minute (defaults to 125)
In VBlank mode:
xx: speed (1-255,ignored)
1.2. Archimedes Tracker V1.0+++ Effect Commands
------------------------------------------
(x-y,z) indicates z is done if value not in the range x to y.
<command character> <command number in hex> <effect value in hex>
0 00 xy Normal play or Arpeggio.
x: first halfnote to add
y: second halftone to subtract
1 01 xx Slide Up.
xx: pitch increase step (4 bits?)
2 02 xx Slide Down.
xx: pitch decrease step (4 bits?)
B 0B xx Break Pattern.
E 0E xy Set Stereo.
y: stereo position (1-7,ignored). 1=left 4=center 7=right
G 10 xx Volume Slide Up.
xx: speed (4 bits?)
H 11 xx Volume Slide Down.
xx: speed (4 bits?)
J 13 xx Position Jump.
xx: song position (0-127,masked)
L 15 xy Line Jump. (not in manual)
Jump to line 10*x+y in same pattern. (10*x+y>63 ignored)
S 1C xy Set Speed.
y: speed (1-15,ignored)
V 1F xx Set Volume.
xx: volume (0-255). Logarithmic.
1.3. Archimedes Symphony V1.00 Effect Commands
-----------------------------------------
(x-y,z) indicates z is done if value not in the range x to y.
<command number in hex> <effect value in hex>
00 xyz Normal play or Arpeggio + Volume Slide Up.
x: volume increase step
y: first halfnote to add
z: second halftone to add
01 xyy Slide Up + Volume Slide Up.
x: volume increase step
yy: pitch increase step
02 xyy Slide Down + Volume Slide Up.
x: volume increase step
yy: pitch decrease step
03 xyy Tone Portamento.
yy: pitch slide speed (0 for previous speed)
04 xyz Vibrato.
y: pitch change speed (0 for previous speed)
z: pitch change depth (0 for previous depth)
05 xyz Tone Portamento + Volume Slide.
y: volume increase step (priority)
z: volume decrease step
06 xyz Vibrato + Volume Slide.
y: volume increase step (priority)
z: volume decrease step
07 xyz Tremolo.
y: volume change speed (0 for previous speed)
z: volume change depth (0 for previous depth)
09 xxx Set Sample Offset.
xxx: offset in sample DIV 128 (loop restarted if illegal)
0 for previous offset
0A xyz Volume Slide + Fine Slide Up.
x: value to add to pitch
y: volume increase step (priority)
z: volume decrease step
0B xxx Position Jump.
xxx: song position (0 if illegal)
0C xyy Set Volume.
yy: volume (0-64,rounded). Linear.
0D xyy Pattern Break.
yy: break position in next pattern (0-63, 0)
0E xxx Not used.
0F xxx Set Speed.
xxx: speed (1-4095,ignored). Default is 6
10 xxy Filter Control. (Not implemented)
y: filter on (0) or filter off (1)
11 xyy Fine Slide Up + Fine Volume Slide Up.
x: value to add to volume
yy: value to add to pitch
12 xyy Fine Slide Down + Fine Volume Slide Up.
x: value to add to volume
yy: value to subtract from pitch
13 xxy Glissando Control.
y: on (1) or off (0) (use with Tone Portamento)
When off, the slide is smooth else from halfnote to halfnote
14 xxy Set Vibrato Waveform.
y: sine (0), ramp down (1), square (2)
bit 2 is off if wave form has to be restarted each note
15 xxy Set Fine Tune.
y: new fine tune value
16 xxx Jump to Loop.
xxx: jump to loop, play xxx times
if 0, the loop start is set to the current pattern position
17 xxy Set Tremolo Waveform.
y: sine (0), ramp down (1), square (2)
bit 2 is off if wave form has to be restarted each note
19 xxx Retrig Note.
xxx: retrig note each (more or less) xxx vblanks
1A xyy Fine Slide Up + Fine Volume Slide Down.
x: value to subtract from volume
yy: value to add to pitch
1B xyy Fine Slide Down + Fine Volume Slide Down.
x: value to subtract from volume
yy: value to subtract from pitch
1C xxx Note Cut.
xxx: cut note after xxx vblanks (volume is only set to 0)
1D xxx Note Delay.
xxx: number of vblanks for note delay
1E xxx Pattern Delay.
xxx: delay pattern xxx notes
1F xxy Invert Loop.
y: speed
if 0, it's turned off
Care must be taken using it: it inverts the sign of sample
data inside sample loop, one byte each vblank
20 xyz Normal play or Arpeggio + Volume Slide Down.
x: volume decrease step
y: first halfnote to add
z: second halftone to add
21 xyy Slide Up + Volume Slide Down.
x: volume decrease step
yy: pitch increase step
22 xyy Slide Down + Volume Slide Down.
x: volume decrease step
yy: pitch decrease step
2A xyz Volume Slide + Fine Slide Down.
x: value to subtract from pitch
y: volume increase step (priority)
z: volume decrease step
2B xyy Line Jump.
yy: Line to jump to in same pattern. (0-63, 0)
2F xxx Set Tempo.
xxx: new tempo value (1-4095,ignored).
Unit: 1/20th vblanks per second (defaults to 1000)
30 xxy Set Stereo.
if y and 7 =0 then xx = stereo position (0-127 is 0 to 127,
129-255 is -1 to -127, 128 ignored)
if y and 7 >0 then y = stereo position (1-7,ignored).
1=left 4=center 7=right
31 xxx Song Upcall.
The CPU performs a linked branch to the song upcall vector.
The routine linked to that vector can corrupt all registers
and must preserve SVC mode on return using MOVS PC,R14
On entry registers contain the following:
R0= xxx parameter
R4= full note address + 4
R5= voice number (0 to 7)
32 xxx Unset Sample Repeat.
The sample continues to be played until it ends, but without loops
2.1. Amiga ProTracker V1.1B Song/Module Format (Filetype &001)
---------------------------------------------------------
Rem: files handled by Amiga ProTracker, NoiseTracker, SoundTracker,
IntuiTracker, ...
Offset Bytes Description
------ ----- -----------
0 20 Songname. Trailing null bytes at the end.
Information for sample 1-31:
Offset Bytes Description
------ ----- -----------
20 22 Samplename. Pad with null bytes.
42 2 Length DIV 2.
44 1 Lower four bits: finetune value (signed 4 bits)
Upper four bits: not used (should be 0).
45 1 Volume for sample 1. Range is &00-&40 (0-64).
46 2 Repeat offset DIV 2.
48 2 Repeat length DIV 2.
Information for the next 30 samples starts here. It's just like the
info for sample 1.
Offset Bytes Description
------ ----- -----------
50 30 Sample 2...
80 30 Sample 3...
.
.
.
890 30 Sample 30...
920 30 Sample 31...
Offset Bytes Description
------ ----- -----------
950 1 Songlength (1-128).
951 1 Well... this little byte here is set to 127, so that old
trackers will search through all patterns when loading.
NoiseTracker uses this byte for restart, but we don't.
952 128 Song positions 0-127. Each hold a number from 0-63 that
tells the tracker what pattern to play at that position.
1080 4 The four letters "M.K." - This is something
Mahoney & Kaktus inserted when they increased the number
of samples from 15 to 31. If it's not there, the
module/song uses 15 samples or the text has been removed
to make the module harder to rip. Startrekker puts
"FLT4" or "FLT8" there instead. "M&K!" may be present,
too.
Offset Bytes Description
------ ----- -----------
1084 1024 Data for pattern 00.
.
.
.
xxxx Number of patterns stored is equal to the highest pattern number
in the song position table (at offset 952-1079).
Each note is stored as 4 bytes, and all four notes at each position in
the pattern are stored after each other.
Position Notes data
-------- ------------------------------
00 chan 1 chan 2 chan 3 chan 4
01 chan 1 chan 2 chan 3 chan 4
02 chan 1 chan 2 chan 3 chan 4
etc.
Info for each note:
-------------------
bits 24-31: effect value (0-255).
20-23: lower 4 bits of sample number (0-15).
16-19: effect command number (0-15).
8-15: lower 8 bits of note period (0-255).
4- 7: upper 4 bits of sample number (0-1).
0- 3: higher 4 bits of note period (0-3).
Period table for Tuning 0, normal:
----------------------------------
C-1 to B-1 : 856,808,762,720,678,640,604,570,538,508,480,453
C-2 to B-2 : 428,404,381,360,339,320,302,285,269,254,240,226
C-3 to B-3 : 214,202,190,180,170,160,151,143,135,127,120,113
To determine what note to show, scan through the table until you find
the same period as the one in the note. Use the index to look up in
a notenames table.
This is the data stored in a normal song. A packed song starts with the
four letters "PACK".
In a module, all the samples are stored right after the pattern data.
To determine where a sample starts and stops, you use the sample info
structures in the beginning of the file (from offset 20). Their format
is linear signed.
ProTracker CIA (Complex Interface Adapter) Timer Tempo Calculations
AMIGA
-------------------------------------------------------------------
Fcolor = 4.43361825 MHz (PAL color carrier freq)
CPU Clock = Fcolor * 1.6 = 7.0937892 MHz
CIA Clock = CPU Clock / 10 = 709.37892 kHz
50 Hz Timer = CIA Clock / 50 = 14187.5784
Tempo num. = 50 Hz Timer*125 = 1773447
For NTSC: CPU Clock = 7.1590905 MHz --> Tempo num. = 1789773
To calculate tempo we use the formula: TimerValue = 1773447 / Tempo
The timer is only a word, so the available tempo range is 28-255 (++).
Tempo 125 will give a normal 50 Hz timer (VBlank).
A normal ProTracker VBlank song tempo can be calculated as follows:
We want to know the tempo in BPM (Beats Per Minute), or rather quarter-
notes per minute. Four notes makes up a quarternote.
First find interrupts per minute: 60 seconds * 50 per second = 3000
Divide by interrupts per quarter note = 4 notes * speed
This gives: Tempo = 3000/(4*speed)
Simplified: Tempo = 750/speed
For a normal song in speed 6 this formula gives: 750/6 = 125 BPM
Note: The mentioned 50 Hz quantities are rather inaccurate since the
vblank frequency is exactly 49.9 Hz!
2.2. Archimedes Tracker V1.0+++ File Formats
---------------------------------------
Sample chunk format
-------------------
This is the component of a Tracker sample file (Filetype &CB5).
Field length Contents
------------ --------
4 bytes The string "SAMP"
4 bytes Chunk length (i.e. total size -8)
4 bytes The string "SNAM"
4 bytes Sample name length (20)
20 bytes Sample name padded with zero's
4 bytes The string "SVOL"
4 bytes Value 4
4 bytes Sample volume (0-255). Logarithmic
4 bytes The string "SLEN"
4 bytes Value 4
4 bytes Sample length (multiple of 4 otherwise Tracker crashes!)
4 bytes The string "ROFS"
4 bytes Value 4
4 bytes Repeat offset
4 bytes The string "RLEN"
4 bytes Value 4
4 bytes Repeat length
4 bytes The string "SDAT"
4 bytes Sample length (multiple of 4): xx
xx bytes Sample data in logarithmic format
Note: the manual states that not all sub-chunks may be present. But
until now they've always been there.
Pattern chunk format
--------------------
This is the component of a Tracker pattern file (Filetype &FF1).
Field length Contents
------------ --------
4 bytes The string "PATT"
4 bytes Chunk length (i.e. number of voices * 256 - the manual
says it's always 2048, that's false! ): xx
xx bytes Notes
Each note is stored as 4 bytes, and all x notes at each position in
the pattern are stored after each other.
Position Notes data
-------- ---------------------------
00 chan 1 chan 2 ... chan x
01 chan 1 chan 2 ... chan x
02 chan 1 chan 2 ... chan x
etc.
Info for each note:
-------------------
bits 24-31: note number (0-36).
16-23: sample number (0-36).
8-15: effect command number.
0- 7: effect value (0-255).
Note numbers table:
-------------------
C-1 to B-1 : 01 to 12
C-2 to B-2 : 13 to 24
C-3 to B-3 : 25 to 36
Module format
-------------
This is the format of a Tracker module file (Filetype &CB6).
Field length Contents
------------ --------
4 bytes The string "MUSX"
4 bytes Chunk length (i.e. total size -8)
4 bytes The string "TINF"
4 bytes Value 4
4 bytes Date of version in BCD format: YYYYMMDD (bytes 1 to 4)
4 bytes The string "MVOX"
4 bytes Value 4
4 bytes Number of voices (1-8)
4 bytes The string "STER"
4 bytes Value 8
8 bytes Default stereo positions for 8 channels. See the command.
4 bytes The string "MNAM"
4 bytes Tune name length (32)
32 bytes Tune name padded with zero's
4 bytes the string "ANAM"
4 bytes Author name length (32)
32 bytes Author name padded with zero's
4 bytes the string "MLEN"
4 bytes Value 4
4 bytes Tune length (1-128)
4 bytes the string "PNUM"
4 bytes Value 4
4 bytes Number of defined patterns (1-64)
4 bytes the string "PLEN"
4 bytes Value 64
64 bytes Length of each pattern (0-64)
4 bytes the string "SEQU"
4 bytes Value 128
128 bytes pattern number to be played at each position (0-63)
This is followed by a pattern chunk for each defined pattern.
After that, there is a sample chunk for each of the 36 samples.
Note that such a file can contain more than one module (MUSX chunk)
but practically it's very rare and not easy to handle...
Such a format for a music module is a bit silly since nearly all
chunks have a constant length.
2.3. Archimedes Symphony Module/Song Format
--------------------------------------
Such tunes are composed of a list of positions which refer to the
pattern that has to be played through a given channel at that song
position. It's possible to play nothing instead of a pattern.
The ranges are as follows:
--------------------------
Voices: 1 to 8
Tune length: 0 to 4096 (&1000)
Pattern number: 0 to 4095 (&FFF)
A pattern is composed of 64 notes.
Each note is stored as 4 bytes (A 32 bit-word), and of course all notes
are stored after each other.
Position Notes data
-------- ----------
00 chan i
01 chan i
02 chan i
etc.
Info for each note:
-------------------
bits 20-31: effect value (0-4095).
14-19: effect command number (0-63).
13-13: not used for now (should be 0).
6-12: sample number (0-63).
0- 5: note number (0-36).
Note numbers table:
-------------------
C-1 to B-1 : 01 to 12
C-2 to B-2 : 13 to 24
C-3 to B-3 : 25 to 36
Note: the use of [x,y] in the following specs refers to the revision
number x and file version y in which the feature first appeared
(see top of this file)
Note2: Any program that would like to read Symphony files should test
the version number and give an error if greater or equal to 10.
The difference between version 0 and 1 is that a version 1 file
MAYBE uses the new packing methods as standard. So read the file
and check if you know the packing methods used.
Note3: You may notice that the space taken by a soundtrack can be
computed without reading the whole file.
Sample file format (Filetype &10A: SySample)
--------------------------------------------
Field length Contents
------------ --------
8 bytes The string "BASSSAMP". Byte value= ASCII code - 64
1 byte Version number (currently 1)
1 byte Name length: xx
xx bytes Name
3 bytes Length DIV 2 (length= number of samples, not bytes)
3 bytes Repeat offset DIV 2
3 bytes Repeat length DIV 2
1 byte Packing method
sy bytes Data:
Packing=0 : 8-bit logarithmic (sy=length)
Packing=1 : 13-bit LZW applied to linear sample data
differences (sy multiple of 4)
Packing=2 : 8-bit linear signed (sy=length) [1,0]
Packing=3 : 16-bit linear signed (sy=length*2) [2,1]
(little endian)
Packing=4 : SigmaDelta compression applied to [2,1]
linear sample differences
Packing=5 : SigmaDelta compression applied to [2,1]
logarithmic sample differences
0-3 bytes Zero's to fill last file word
Pattern file format (Filetype &FFD: Data)
-----------------------------------------
Field length Contents
------------ --------
8 bytes The string "BASSPTRN". Byte value= ASCII code - 64
1 byte Version number (currently 0)
1 byte Contents: 0 for a sequence, 1 for some patterns
0-1 byte Number of sequence lines (only if Contents=0): z
2 bytes Length: number of sequence positions
or number of patterns: xx
yy bytes Data:
Contents=0 : For each line
For xx positions
Pattern number (2 bytes each)
(yy=2*xx*z)
Contents=1 : patterns data (yy=256*xx)
Module/Song file format (Filetype &10B: Symphony)
-------------------------------------------------
Field length Contents
------------ --------
8 bytes The string "BASSTRAK". Byte value= ASCII code - 64
1 byte Version number (currently 1)
1 byte Number of voices (1 to 8): z
2 bytes Track length in positions: y (0 to &1000)
2 bytes Number of defined patterns: p (0 to &1000)
3 bytes Information text length: il
For the 63 samples, we have:
( 1 byte Sample name length: sn
( (bit 7 set if all its data is blanked: lengths, vol, ft)
( (bit 6 reserved => mask out to read / write 0)
( 3 bytes Sample length DIV 2 (length= number of samples, not bytes)
1 byte Track name length: x
x bytes Track name
8 bytes Effects allowed table. 1 bit per effect (0=no, 1=allowed)
If y>0 then
( 1 byte Packing system for sequence (0= not packed, 1= packed)
( s bytes Sequence data:
( Packing=0 : For each position
( For each voice
( Pattern number (2 bytes)
( (s= 2*y*z)
( Packing=1 : 13-bit LZW applied to overall sequence data
( (s multiple of 4)
If p>0 then
( For each pk-pattern chunk (all 2000 patterns but the last):
( 1 byte Packing system for chunk (0= not packed, 1= packed)
( b bytes Pattern data:
( Packing=0 : For each pattern
( For each pattern position (0 to 63)
( Full note value (1 word)
( (b= 4*64*pk)
( Packing=1 : 13-bit LZW applied to chunk data
( (b multiple of 4)
For the 63 samples, we have:
( sn bytes Sample name
( 3 bytes Sample repeat offset DIV 2
( 3 bytes Sample repeat length DIV 2
( 1 byte Sample volume (0 to 64)
( 1 byte Sample fine tune (-8 to 7)
( 1 byte Packing system for sample (see sample file format)
(
( If sample length>0 then
( ( sy bytes Data: see sample file format above
If il>0 then
( 1 byte Packing system for information text
( (0= not packed, 1= packed)
( i bytes Information text:
( Packing=0 : Text (i=il)
( Packing=1 : 13-bit LZW applied to information text
( (i multiple of 4)
0-3 bytes Zero's to fill last file word
Notes about compression algorithms:
- Sample differences are computed like this:
Init: x=0; p=sample start
Loop: difference= value(p)-x; x= value(p); inc(p)
- The 13-bit LZW compression scheme uses 256/257 as restart/end code.
Applied on signed linear sample deltas.
- The SigmaDelta compression is rather too complex to explain here!
Applied on unsigned linear or unsigned logarithmic sample deltas.
Maybe next time we'll provide some algorithms...
=========================================================
PART II : Digital Symphony SWI's and commands information
=========================================================
The following explains the functionalities used in the 1 music-player module
(the one generated by the Digital Symphony application) and in the
multi music player module (files DSymPlay and DSymPlayA3). The file DSymPlayA3
only differs from the file DSymPlay in that only the routines used whenever
a cached processor (e.g. ARM3) is detected are present in it, so you gain
some Kbytes space (~16K) but have slower routines when used with non-cached
processors (e.g. ARM2, ARM250).
THESE MODULES ARE FREEWARE. If you use it in a NON COMMERCIAL program (we
strongly encourage it) then all we ask is:
- In all cases, give some credits to BASS for the playroutine.
- If the play module stays as a stand-alone module in your app directory,
then include this text file unaltered too.
If you wish to use them in some commercial software then contact
Oregan Developments for an agreement. See the end of this file for addresses.
Now more technical details.
In order to keep the code size low and the whole CLI command names clean, this
player only offers SWI's. But hopefully a CLI command gives access directly
to these SWI's for the CLI user.
Nearly all SWI's should never be used while interrupting the player routine
(i.e. they're not reentrant). See the SWI that allows to know if the player
routine has been interrupted or not.
You can call a SWI via this * command:
*DSym <SWI name> [<R0 value> [<R1 value> [<...>]]]
Of course you can't get results back this way.
The unspecified values are set to 0 before calling the corresponding SWI.
A value may be:
- Any string readable by the OS_ReadUnsigned SWI (see the PRM's).
- The latter string preceeded by the minus sign for a negative number.
You can specify a pointer to a string (i.e. when a file name is required)
only for R0 value: just put the string between quotes.
Some examples:
Set the overall volume to 64: *DSym Vol 64
Load file $.MegaMix: *DSym Load "$.MegaMix"
Set stereo of channel 2 to -127: *DSym Stereo 2 -&7F
Instead of installing the player module in RMA (that requires to ensure
there's enough memory free in RMA, very annoying in demos), you could
directly patch the module into your code. There are 2 ways to do this:
- Link it to modules chain in RMA using OS_Module 10 (See the PRM's). The
SWI's are always available. Don't forget to kill it before returning to
desktop!
- Don't link to other modules. The SWI's are not directly available.
Let's assume ModStart to be the start address of the player module in
your code. First you must call (ModStart+(ModStart!4)) like RISC OS
would do when loading a module. Now you can use SWI's by calling a
special routine with R11 containing the SWI number. For example, set the
volume to 64 with:
MOV R0,#64 ; SWI parameter
MOV R11,#2 ; SWI number
BL ModStart+44 ; Note: need NOT be in SVC mode
Finally don't forget to call (ModStart+(ModStart!8)) before your
program exits.
The advantages of using a generated 1 music-player are as follows:
- Only the useful routines are included. E.g. the rather big loader routine
is not included.
- The tune data is arranged to get more efficient results through
compaction. In fact, samples are stored as linear deltas.
- Several parameters can be set by default at module installation, such as
looping, play or not when module installed...
Also an advantage in the multi music-player from version 1.40 on:
At module's installation (or song loading for the multi-player), the
samples data are scaled to the current configured volume of the machine.
This gives more chances that the efficient sound buffer filling routines
in the case of no scaling are used. It's of no help if the global volume
is not at maximum or a sample is not played at full volume.
WARNING here: when using the InstrData SWI, the newly installed sample
is scaled too, so avoid calling twice with exactly the same parameters
without refreshing the real sample data!
The SWI's allow you to play tunes in your own programs and making sound
effects. While the tune is playing you can make additional sound effects
(produce 'custom notes') in the same way the tune does. In fact, you could
play a tune by producing notes stored in your own tables.
If you'd like to play your notes while the tune is playing, you can do it
on the voices used by the tune, but with some tunes there can be some clashes
with samples and notes (this is ONLY a matter of nice sound and NOT a matter
of bugged routines). So it's preferable to play them on the free voices
(the ones with the highest numbers). For example, with a tune with 3 rows
in its sequence and 4 configured voices, you could safely play your notes on
the 4th voice.
Useful example:
---------------
Prototype for playing a song in a usual program:
SYS"DSym_Load","<Prog$Dir>.Music" :REM Load song in RMA
SYS"DSym_RestartSong" :REM Start playing
REPEAT
REM Main loop
UNTIL exit%
FOR v%=64 TO 0 STEP -1 :REM Fade out
SYS"DSym_Vol",v%
WAIT
NEXT
*RMKill DSymphonyPlayer
To stop a tune: SYS"DSym_Pause"
To continue after a stop: SYS"DSym_TuneControl",1 or SYS"DSym_RestartSong" to
restart.
Some other possible effects:
- Engine noises, changing volume and finetune (see effects 11 & 12).
- Manipulate a lot of samples without loading new tunes, using the InstrData
SWI.
- ...
More technical details:
-----------------------
SWI Chunk name: DSym
SWI Chunk base number: &45880 (allocated from Acorn)
Should work on A5000's and some VIDC enhancers (i.e. no pitch bending)
without any additional code. See SWI to set hardware speed.
SWI DSym_Load does not work in the 1 music-player.
The player can only load Digital Symphony format files because it would eat
too much memory (makes me think of other players...). It was designed to
be as 'simple' as possible. It cannot read 16-bit samples.
The player does NOT use the VIDC pointer.
The player does NOT use WAIT's.
The player does use OS_ReadMonotonicTime only:
- When calling DSym_Configure, DSym_Load or the module finalisation entry.
- In the buffer filling routine when in 'auto speed' mode (in order to
'guess' the current VIDC speed) (see SWI HardSpeed)
So let the interrupt for the corresponding timer enabled in those cases.
The FillAddress SWI allows you to know the address of the buffer filling
routine (you could get it with Sound_Configure but it's easier here).
If you feel pretty good you could then call it yourself instead of RISC OS
each time a sound interrupt occurs. You must call DSym_Configure at least
once before using the filling routine.
The specs for the filling routine:
Entry: R12 points to buffer to fill (word-aligned, length=1664 bytes)
Processor in IRQ mode
IRQ disabled
Exit: R0-R12,R14 and flags corrupted
Processor in IRQ mode
IRQ disabled
Buffer filled for the number of configured voices (208 bytes/voice)
The routine enables IRQ's during its work.
You are expected to make no mistakes when passing parameters to SWI's. If
you do, it's possible that the machine locks up! (Remember: the player is
powerful but simple)
Note: There are two SWI's to set the stereo positions. A front-end
application that sets the current stereo should set the DEFAULT stereo
too.
Note2: In the following specs, no reference to a register on exit means
it is preserved.
Note3: It is recommended that you set the sample quality (SampleRate SWI)
to something other than the default 24. 24 is usually not convenient
when CPU power is needed for other things than music. This is
especially true if it has to run on an ARM2.
Note4: The terms 'custom note buffer' and '1-entry-per-voice buffer' used
below refer to the buffer used to store notes triggered by some SWI's
below before they are really played by the interrupt routine. Two
notes played just one after each other probably means that only the
lastest one will be taken into account. Some SWI's allow to solve that
problem by controlling the empty state of the buffer.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SWI name Nr !Entry !Exit/Effect
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Load 00 !R0=-1 to free RMA buffers !If an error occured, then
!or R0= 0 to load from ! R0 points to error
! memory ! and V is set,
!or R0 points to file name !else
!R1= source start address ! R0= length of track
! (if R0=0) ! in memory.
!R2= 0 to load to RMA !
!or R2= destination start !
! address !
!R3= size of destination !
! buffer (if R2<>0) !
!R4= 0 to claim buffer !
! in RMA !
!or R4= start address of !
! buffer (32K space) !
!A buffer address is needed only if the Symphony file
! contains some packed data.
!Buffers are word aligned.
!In the case of packed data, the source and destination
! buffers can't share any part of memory.
!In the case of entirely non packed data, the two buffers
! can share a part of memory provided
! destination address <= source address. After the call
! the source data has been altered because the
! module needs to build an internal structure different
! to the source structure of the tune.
!Although the code is quite optimized, loading from
! memory may take some time because all the data has to
! be moved in memory. So don't expect loading 50 songs
! per second with an ARM2!
--------------------+--------------------------+-----------------------------
RestartSong 01 ! - !Do a ResetParams,
! !Tune position set to (0,0),
! !Tune playing again.
--------------------+--------------------------+-----------------------------
Vol 02 !R0= new overall volume !R0= previous overall volume
! or -1 to read ! (0-64).
!Initial value is 64 !
--------------------+--------------------------+-----------------------------
Stereo 03 !R0= voice number (0-7) !R1= previous stereo position
!R1= new stereo position ! (-127 to 127) for voice
! or -128 to read ! number R0.
! !
!Initial values are those of the Amiga.
--------------------+--------------------------+-----------------------------
CutNote 04 !R0= voice number (0-7) !R1= previous note state on
!R1>=0 to read state ! voice number R0
! < 0 to stop note ! < 0 -> stopped
! ! >=0 -> playing, = sample
! ! start address
! !If R1>=0 then
! ! R2= offset in sample
! ! in 1/(2^12) units
--------------------+--------------------------+-----------------------------
PlayInstrPacked 05 !R0= voice number (0-7) !The new note is put into a
!R1= full note data !1-entry-per-voice buffer to be
!R5= minimum sustain time !played.
! (in 1/50th sec) !Setting a sustain time means
!R6<>0 to wait for buffer !that the new note has
! empty !priority on the tune notes
! else don't wait !during this time.
--------------------+--------------------------+-----------------------------
PlayInstr 06 !R0= voice number (0-7) !The new note is put into a
!R1= note number (0-36) !1-entry-per-voice buffer to be
!R2= sample number (0-63) !played.
!R3= effect number (0-63) !Setting a sustain time means
!R4= effect value (0-&FFF) !that the new note has
!R5= minimum sustain time !priority on the tune notes
! (in 1/50th sec) !during this time.
!R6<>0 to wait for buffer !
! empty !
! else don't wait !
--------------------+--------------------------+-----------------------------
ResetParams 07 ! - !All parameters are reset
! !(stereo,counters,effects,...)
! !and do a FlushOutput.
--------------------+--------------------------+-----------------------------
FlushOutput 08 ! - !The current notes on all
! !channels are cut.
--------------------+--------------------------+-----------------------------
FreezeOutput 09 !R0= -1 to read output !R0= previous output status
! status !( 0= off ie. no sound output
! <>-1 to set ! <>0= on )
--------------------+--------------------------+-----------------------------
UpCallVector 0A !R0= -1 to read upcall !R0= previous upcall address
! address !
! = -2 to set default !
! else new address !
--------------------+--------------------------+-----------------------------
MaskVoice 0B !R0= voice number (0-7) !R0= previous voice status
!R1= -1 to read voice stat ! (0= off, <>0=on)
! <>-1 to set voice status!The notes are still played
! !but not heard for the voice.
--------------------+--------------------------+-----------------------------
SongPos 0C !R0= -1 to read sequence ps!R0= previous sequence pos
! <>-1 to set !R1= previous pattern pos
!R1= -1 to read pattern pos! (0-63)
! <>-1 to set !If pattern pos is changed
! !then the current counter is
! !reset to play the tune line
! !as soon as possible.
--------------------+--------------------------+-----------------------------
TuneControl 0D !R0= -1 to read status !R0= previous tune status
! <>-1 to set (lower byte)! (0= off, <>0= on)
! !Off means the tune decoder
! !won't let play notes anymore,
! !you can still play custom
! !notes.
! !Current notes still playing.
--------------------+--------------------------+-----------------------------
Pause 0E ! - !The tune is stopped and
! !current notes on tune
! !channels cut.
--------------------+--------------------------+-----------------------------
Voices 0F !R0= -1 to read hardware !R0= previous hardware voices
! voices number ! number (1,2,4 or 8)
! <>-1 to set voices !
!The change is taken into account during next configure.
!Initial value is 4.
--------------------+--------------------------+-----------------------------
Wait 10 !R0= voice number (0-7) !C is set if custom note
! !buffer is not empty,
! !else clear.
--------------------+--------------------------+-----------------------------
IntState 11 ! - !C is set if the call has
! !interrupted the playing or
! !filling routines.
--------------------+--------------------------+-----------------------------
NoteInfo 12 ! - !R0= address of current notes
! ! table (1 word per voice)
! ! note is 0 to 1023
! !R1= address of current
! ! samples table (1 byte per
! ! voice)
! ! sample is 0 to 63
! !R2= address of effects table
! ! (1 word per voice)
! ! bits 30-31 meaningless
! ! bits 16-21 effect nr
! ! bits 0-11 effect value
! !R3= address of volumes table
! ! (1 byte per voice)
! ! volume is 0 to 64
--------------------+--------------------------+-----------------------------
VuBar 13 !R0= voice number (0-7) !R1= Vu bar height (0-64)
--------------------+--------------------------+-----------------------------
Loop 14 !R0= -1 to read loop contrl!R0= previous loop control
! <>-1 to set ! ( 0= enabled,
!R1= -1 to read loop flag ! <>0= disabled )
! <>-1 to set !R1<>0 if the tune has looped
! ! else not looped
! !
!Loop control is initially enabled.
!If a song has looped and the loop is disabled, you can
!continue playing using TuneControl.
--------------------+--------------------------+-----------------------------
BufferAddress 15 ! - !R0= current system hardware
! ! buffer address (with
! ! output data interleaved)
! ! 208 bytes per channel
--------------------+--------------------------+-----------------------------
VuGravity 16 !R0= -1 to read Vu gravity !R0= previous gravity of Vu
! <>-1 to set (lower byte)! bars (0-255)
!Initial value is 2. !
!The change is taken into account during next configure.
--------------------+--------------------------+-----------------------------
SampleRate 17 !R0= -1 to read sample rate!R0= previous sample rate
! <>-1 to set ! (0-99) - determines
! ! sample output density.
!Original value is 24. !
!The change is taken into account during next configure.
--------------------+--------------------------+-----------------------------
Configure 18 !R0= -1 to reinstall previous
! configuration
! <>-1 to configure the system
! with new voices number,
! sample rate, Vu gravity and hardware speed.
--------------------+--------------------------+-----------------------------
Params 19 ! !R0= speed (1-&FFF)
! !R1= tempo (1-&FFF)
! !R2= counter (0-&FFE)
!The counter varies from 1 to speed-1 at a speed
!according to tempo (50 times a sec for default tempo)
--------------------+--------------------------+-----------------------------
TuneInfo 1A ! - !R0= tune length
! !R1= number of patterns
--------------------+--------------------------+-----------------------------
PlaySingle 1B ! R0= -1 ! Play pattern R1
! or ! or
! R0<>-1 ! Play from pos R0 to R1
! !
! and !
! R2= -1 for no loop !
! <>-1 to loop !
! !
! or R0=-1 and R1=-1 ! or Normal play.
! !
! !The pattern pos is set to 0.
! !In the case of playing a
! !part of the sequence, the
! !current position is set to
! !the first pos in that part.
--------------------+--------------------------+-----------------------------
DefaultStereo 1C !R0= voice number (0-7) !R1= previous default stereo
!R1= new default stereo !position (1 to 7) for
! position !voice number R0
! or 0 to read !
! !
!Initial values are those of the Amiga.
--------------------+--------------------------+-----------------------------
InstrData 1D !R0= sample number (1-63) !The specs for sample R0
!R1= sample data address !are changed to those on entry
! or -1 to read !R1= previous address
!R2= sample length !R2= previous length
! or -1 to read !R3= previous repeat offset
!R3= repeat offset !R4= previous repeat length
! or -1 to read !R5= previous volume
!R4= repeat length !R6= previous finetune
! or -1 to read ! (-8 to 7)
!R5= volume (0-64) !
! or -1 to read !
!R6= finetune (0-&F) !
! or -1 to read !
!R1 to R4 must be 2-byte aligned.
!Put a repeat length of 0 for no repeats.
!Repeat length can't be 2.
!Set bit 31 of R1 if the sample is signed linear.
!The data is not moved i.e. it stays where you put it.
!The data is also scaled to the current machine volume if
!R1<>-1.
--------------------+--------------------------+-----------------------------
HardSpeed 1E !R0= samples output !R0= previous parameter
! frequency (in kHz) !R1= current hardware speed
! or 0 for 'auto speed' ! (in kHz)
! or -1 to read !The buffer filling routine
! !output frequency is changed
! !to the one on entry
!Initial mode is 24000 !
!The change is taken into account during next configure.
!
!In 'auto speed' mode, the filling routine will try to
!guess the current VIDC frequency for outputting samples
!by averaging the number of calls to it and adjust its
!tables to always have the same real pitch whatever the
!hardware speed is. The 'auto speed' selects one of the
!three following speeds currently:
!
! 24000 kHz (normal modes)
! 25175 kHz (VGA modes)
! 36000 kHz (multi sync modes)
!
!Too bad to have the same clock for graphics and sound!
--------------------+--------------------------+-----------------------------
LoopType 1F !R0= loop type !R0= previous loop type
! or -1 to read ! (0 or 1)
! !
!Type 0: The loop flag is set if the tune reaches
! position 0.
!Type 1: The loop flag is set if the tune jumps to
! a lower position.
--------------------+--------------------------+-----------------------------
FillAddress 20 ! - !R0= address of buffer filling
! ! routine
--------------------+--------------------------+-----------------------------
So, with such a tool in the hands of (good) demo and game writers, we hope
to see more and more demos and games with decent (if not very good) sound,
and never listen again to the horrible *noises* made by previous (and some
current) lamer samples and SoundTrackers replayers!!!
Before giving our addresses, we'd like to thank the following people/groups
for their constructive remarks and questions and bug reports concerning
this player:
SICK
ARMAXESS
George Saliaris
If you find any bug or have any comment about this player or even Digital
Symphony, don't hesitate to contact us at one of the addresses below:
+----------------------------------------------------------------+
! You can contact the guys who made this software at !
+--------------------------+-------------------------------------+
! Bernard Jungen ! Gil Damoiseaux !
! Friddericht 27 ! Rue du Bois des Broux 5 !
! B-6706 Autelbas ! B-5080 Rhisnes !
! Belgium ! Belgium !
! ! !
! E-mail (until end 1999): ! !
! bju@cediti.be ! !
+--------------------------+-------------------------------------+
+----------------------------------+
! John Tytgat !
! Brusselbaan 445 !
! B-1600 St.-Pieters-Leeuw !
! Belgium !
! !
! E-mail: !
! john.tytgat@barco.be !
+----------------------------------+
If you would like to use our play routines in commercial products, or simply
want to buy Digital Symphony itself, then contact:
+-------------------------------------------------------------------+
! You can obtain a fully multi-tasking sound tracker editor, called !
! Digital Symphony, which takes ProTracker, (Octo)MED, Tracker, !
! Coconizer and native Symphony files as input from !
+-------------------------------------------------------------------+
! Oregan Developments, !
! 36 Grosvenor Avenue, Streetly, !
! Sutton Coldfield B74 3PE, !
! England. !
+-------------------------------------------------------------------+
© 1992/1996 B. Jungen & G. Damoiseaux (members of BASS).